package com.hainatong.mvvmbase.http.httpstool;

import android.content.Context;
import android.util.Log;

import javax.net.ssl.*;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;

public class HttpsUtil
{
        // 请求服务器的主机名称
        private static final String HOST_NAME = "xxxxxx";

        // 下载的证书的文件名称
        private static String CERTIFICATE_NAME = "wuliang.cer";

        private static HttpsUtil instance;

        private X509TrustManager trustManager;

        private SSLSocketFactory sslSocketFactory;

        public static HttpsUtil getInstance(Context context)
        {
            if (instance == null)
            {
                instance = new HttpsUtil(context);
            }
            return instance;
        }

    private HttpsUtil(Context context)
        {
            try
            {
                trustManager = trustManagerForCertificates(trustedCertificatesInputStream(context));
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, new TrustManager[] {trustManager}, null);
                sslSocketFactory = sslContext.getSocketFactory();
            }
            catch (GeneralSecurityException e)
            {
                throw new RuntimeException(e);
            }

        }

        public SSLSocketFactory getSslSocketFactory()
        {
            return this.sslSocketFactory;
        }

        public X509TrustManager getTrustManager()
        {
            return this.trustManager;
        }

        private InputStream trustedCertificatesInputStream(Context context)
        {
            InputStream inputStream = null;
            try
            {
                inputStream = context.getAssets().open(CERTIFICATE_NAME);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return inputStream;
        }

        // 获取证书
        private X509TrustManager trustManagerForCertificates(InputStream in)
        throws GeneralSecurityException
        {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
            if (certificates.isEmpty())
            {
                throw new IllegalArgumentException("expected non-empty set of trusted certificates");
            }

            char[] password = "password".toCharArray();
            // Put the certificates a key store.
            KeyStore keyStore = newEmptyKeyStore(password);
            int index = 0;
            for (Certificate certificate : certificates)
            {
                Log.d("OkHttp", "trustManagerForCertificates: " + certificate.toString());
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificate);
            }
            // Use it to build an X509 trust manager.
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, password);
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager))
            {
                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
            }
            return (X509TrustManager)trustManagers[0];
        }

        // https 请求相关

        private KeyStore newEmptyKeyStore(char[] password)
        throws GeneralSecurityException
        {
            try
            {
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                InputStream in = null;
                keyStore.load(in, password);
                return keyStore;
            }
            catch (IOException e)
            {
                throw new AssertionError(e);
            }
        }


        public static class TrustHostnameVerifier implements HostnameVerifier
        {

            @Override
            public boolean verify(String hostname, SSLSession session)
            {
                // hostname:本次请求的域名，如果域名是我们认可的域名，那么返回true，
                // 本次请求继续执行，返回false会中断本次请求
                // return hostname.equals(HOST_NAME);

                Certificate[] localCertificates = new Certificate[0];
                try
                {
                    // 获取证书链中的所有证书
                    localCertificates = session.getPeerCertificates();
                }
                catch (SSLPeerUnverifiedException e)
                {
                    e.printStackTrace();
                }
                // 打印所有证书内容
                for (Certificate c : localCertificates)
                {
                    Log.d("OkHttp", "verify: " + c.toString());
                }
                // 如果不进行校验，直接return true，代表信任所有请求
                return true;
            }
        }
}